Skip to content

Preserve opted-in condition occurrence deadlines across false wakes - #1067

Merged
rmcdaniel merged 5 commits into
mainfrom
fix/condition-occurrence-deadline-general-20261108
Nov 8, 2026
Merged

rmcdaniel merged 5 commits into
mainfrom
fix/condition-occurrence-deadline-general-20261108

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

An opted-in condition wait now retains its first wall-clock deadline across false-wake reopens. A worker can author a remaining timeout while the runtime schedules the new timer at the original occurrence anchor, including when that deadline has already passed.

The command fields are deadline_policy: "occurrence" and condition_wait_timeout_budget_seconds. The first physical open must use the full budget. Every reopen must keep the occurrence ID, key, fingerprint, policy and budget. The anchor comes from the first timer row, which remains authoritative after cancellation. A validated still-open repeat retains its existing wait without consuming another sequence; an elapsed anchor becomes a pending due timer.

Mismatches, a fired timeout and an unavailable anchor refuse before any completion effects commit. The run lock and whole-completion transaction also cover signal resume and earlier sibling commands. Existing legacy chains keep their per-open behavior; opting into or out of an existing chain is refused.

Core advertises worker protocol 1.22 and continues accepting 1.20 requests. Opened history records policy, original budget and anchor; TimerScheduled records policy and anchor, matching Native #1098. The change includes payload validation, history retention, replay corpus growth, documentation and causal bridge controls. PHP Server capability advertisement and package delivery follow separately.

Validation on head e5e161699d920ab127713a7e5cc033de79b3e90e:

  • Pull-request checks: 17 successful, 7 intended skips.
  • Local selected ECS and protocol contracts: 46 tests, 384 assertions; earlier source checks cover static analysis, condition controls and the replay corpus.
  • Independent Server source review and three narrow addenda: source, history parity, future-version fixtures, manifest expectation.
  • Full maintained qualification 42455200291 passed: 5,928 unit tests / 80,823 assertions, all database feature lanes and 93.90% combined coverage against the unchanged 93.08% baseline. Earlier 15 notices and 49 unit skips remain recorded.

The earlier corpus-growth, stale future-version and manifest-expectation failures remain attributed in the issue comments. No package release or installed-runtime acceptance is claimed here.

Refs #1066, durable-workflow/sdk-php#269, durable-workflow/server#1098.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Independent Server cross-contract source review (Security Off): SOURCE PASS, with one cross-runtime parity follow-up and four non-blocking notes.

Subject (exact):

  • Head 9b896fa4e3031c30f3032307ab70833248c909ef, tree a3b2f1db099ec34c3190b7a2fbd28695be83b3ca, sole parent and base 36961d60921dd7190890a505d9364f1f712a8d63.
  • Full git diff --binary 40,301 B / b669bc74a22b058c617bbc29b357c9677cf1bcf43e8bbe541474db978baec68b; 12 files, +596/−10. I read all of it.
  • Compared against Native Keep an opted-in condition occurrence's first-open wall deadline (sdk-php#269) server#1098 (head 5f937ec8, tree f6f391d9) and sdk-php#364 (merge 8016c264).
  • Source reading only: no build, test or container run. Hosted ECS, unit, coverage and feature remain required.

Requested checks

Contract point Result
Original budget vs remaining ConditionOccurrenceDeadline::fields requires policy occurrence, integer 0 ≤ timeout_seconds ≤ budget, and a non-empty occurrence. The first open requires remaining = budget; a reopen may author less. The new timer keeps delay_seconds = remaining, and fire_at = A. This matches Native occurrence_deadline/First and SDK364, which authors budget = timeout on the first open and copies the recorded budget on reopens.
Canonical first timer A is read from the timer row for chain[0] by run and timer ID, with its sequence checked. The chain is in history order, so chain[0] is the first open. Status is not filtered, and cancelOpenConditionTimer only marks the row Cancelled, so a cancelled first timer still supplies A. A missing row, a wrong sequence or a missing fire_at refuses condition_wait_anchor_unavailable, never a fresh budget. Same as Native Reopen.
Still-open identity/policy Every wait in the chain, including the still-open one, is checked for policy, budget, key and fingerprint, and for timer fired, before keep_open returns. The kept repeat does not advance the sequence (Native StillOpen returns before sequence += 1). Tested with same-batch siblings: key, fingerprint, budget and omission each give condition_wait_occurrence_mismatch; [$command, $command] keeps one open and one timer.
Downgrade refusal An anchored chain plus an open without the policy gives mismatch; a legacy chain plus a later opt-in gives anchor_unavailable. Both match Native, and both are tested after a signal resolution.
Whole-completion rollback Both completion entries run in meteredTransaction with the run lockForUpdate. Lifecycle events are withheld until commit, and the conflict is caught outside the transaction at both sites. Signal resume (recordAppliedSignal…, recordSatisfiedConditionWait…, the first-timer cancel) and earlier siblings run inside it. Tests assert an unchanged history count, the first timer still Pending after a refused downgrade, zero timers after a refused batch, and the lease retained.
Past A fireImmediateConditionTimeout runs only when timeout === 0 && deadline_at === null. An anchored open with timeout 0 creates a Pending timer whose task available_at = A. Tested: no TimerFired at completion; RunTimerTask then fires with fire_at = A and fired_at = now; a later reopen refuses condition_wait_occurrence_timed_out. Native passes Some(A) for First and Reopen, so it never fires inline either.
Legacy compatibility Without the policy, resolve returns a null deadline. Both payloads are array_filtered, so legacy ConditionWaitOpened/TimerScheduled bytes and keys are unchanged, and the timer and inline-fire branches are unchanged. The occurrence_deadline_at format (toJSON, microseconds) matches Native iso (SecondsFormat::Micros).
Protocol Core VERSION goes 1.21 → 1.22 as additive metadata. isSupportedRequestVersion accepts 1.20–1.22 and refuses 1.23. The normalizer test keeps the fields under a '1.20' request. The Server PHP app keeps its own WorkerProtocol::VERSION = '1.20' (and pins workflow 2.15.12), and sdk-php sends Version::WORKER_PROTOCOL = '1.20'. So neither Native's request floor nor its advertisement changes, and no Native protocol bump is needed.

Finding 1: cross-runtime history shape (parity follow-up, owner Server; not a defect in this PR)

The anchored TimerScheduled payloads differ between the runtimes:

  • This PR adds deadline_policy, condition_wait_timeout_budget_seconds and occurrence_deadline_at (via ...$deadlineMetadata).
  • Native #1098 (schedule_wait_timeout) adds only deadline_policy and occurrence_deadline_at. Its wait_fields does not copy the budget.

The ConditionWaitOpened payloads agree. No anchoring decision reads the budget from TimerScheduled: both runtimes fold it from ConditionWaitOpened. Even so, the same workflow produces different TimerScheduled keys on PHP and Native. Recommendation: align Native by adding the budget to its anchored TimerScheduled, a one-line additive change, as a separate Server train after #1098 custody. That should land before any shared corpus or cohort case covers anchored chains. PHP's HistoryEventPayloadContract already allows the field, so this PR needs no change.

Non-blocking notes

  1. Grouped waits. Neither runtime refuses the policy on an open with parallel_group_path; SDK364 never emits it for grouped waits. In PHP an opted-in grouped first open is anchored, but a grouped reopen with a smaller remaining timeout fails recordedGroupedConditionReopenMatches, which compares timeout_seconds with the original, and so returns invalid_commands. That behavior is incidental. A later change should either refuse the policy on grouped opens in both runtimes or define support explicitly.
  2. Budget range (pre-existing). PHP bounds neither timeout_seconds nor the budget from above, while Native refuses values it cannot represent with a 422. A huge budget in PHP fails like the existing huge-timeout path rather than with invalid_condition_deadline_policy.
  3. Whitespace-only occurrence IDs. Under the policy PHP refuses them (trim); Native accepts any non-empty string. This follows the existing occurrence-identity normalization difference and is edge-only.
  4. Test gaps. No test covers a chain of three or more opens (reuse of the first timer, not the latest), a timer-sequence mismatch, or the second completion entry's rollback. That entry shares meteredTransaction and the catch, so it is covered by construction.

Scope

After this PR, the Server PHP app still does not advertise condition_wait_occurrence_deadline: its parity fixture lists it as a Native addition, and it pins an older workflow release. PHP-server parity therefore needs a separate Server capability and fixture change once a workflow release containing this PR exists. This review makes no release, image, runtime or installed-acceptance claim. Server #269's installed wall-deadline acceptance remains open.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Source addendum to 6717674660: SOURCE PASS for the successor. Finding 1 is resolved.

Subject (exact):

  • Head 4336420dd63345daec504f34bfd4f4702273e6ac, tree 37bd17a031eb3742b62bf381fa085d714e8918ad. Its sole parent is the reviewed 9b896fa4, on base 36961d60.
  • Full diff against the base: 47,408 B / 5dd9f31ca7e9c3e6b992d2291ebe2c0a5ba5695638c7cb7c27654d7dd6d30b0b.
  • Successor-only delta: 9,150 B / 624f9c21a65190ff36ba92d71cb1f9a78794ac5969dc3f6996a8f856d492e3fd. I read all of it: 4 files, +194/−2.
  • Source reading only.

The delta:

  • DefaultWorkflowTaskBridge. The anchored TimerScheduled payload now carries only deadline_policy and occurrence_deadline_at, matching Native #1098 schedule_wait_timeout. condition_wait_timeout_budget_seconds stays on ConditionWaitOpened, carried by $deadlineMetadata as before. On a legacy chain both keys are null, and the existing array_filter removes them, so legacy TimerScheduled bytes are still unchanged. Nothing else in the bridge changed.
  • HistoryEventPayloadContract. The budget is removed from the TimerScheduled key list and stays in the ConditionWaitOpened list. 9b896fa never merged, so no stored history carries the removed key.
  • Bridge test. For anchored chains it now asserts that both opens record budget [20, 20], and that every TimerScheduled has policy occurrence, occurrence_deadline_at equal to the first timer's fire_at, and no budget key. This pins the full distinction.
  • Replay fixture condition-occurrence-deadline-history-retention.json. It replays history shaped like Native's: rust:condition-wait:N occurrences, budget on Opened, policy and A on TimerScheduled. It checks that the PHP replayer accepts the anchored metadata and keeps both occurrence IDs. Its two anchors are consistent with their opens: 19:40:01 + 20 s = 19:40:21, and 19:40:04 + 20 s = 19:40:24.

Cross-runtime check: anchored ConditionWaitOpened and TimerScheduled payloads now use the same key sets in Core and Native. Timestamps are microsecond ISO on both sides. No Native change is needed.

Unchanged from the first review: all deadline, anchor, still-open, downgrade, rollback, past-A and legacy behavior, plus the Core 1.22 decision and old-request compatibility. The four non-blocking notes still stand.

One optional strengthening: the fixture's two waits are separate first opens. A same-occurrence reopen in replay (remaining < budget, A reused) is covered only by the bridge test.

Hosted ECS, unit, coverage and feature on this exact head are still required. 9b896fa's hosted NONPASS (corpus count) stays attributed to that head. This addendum makes no release, runtime or installed-acceptance claim.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Hosted qualification of head4336420d is NONPASS: pr-feature-mysql, run42451248044/job128640956311, reached the service scheduling/completion contracts and failed 1 of228 cases. DefaultWorkflowTaskBridgeServiceOperationTest::testInvalidCompletionProtocolIsRejectedBeforeAnyWrite@future minor still used1.22, now the supported revision, as an unsupported version. This is a stale test expectation. The other227 cases passed. Other exact-head checks were15success/7gatedskip; aggregate build also failed. No rerun of the failed assertion was selected.

The current successor is 68e7f3d, tree 88b3f26df228a1d7b50701ebf12c453c8766d80b. The only delta from reviewed4336420d is changing the future-minor input1.22→1.23 in that unit test and the matching webhook feature test. Both still require unsupported_protocol_version before writes. WorkerProtocolVersionTest already positively supports1.22 and refuses1.23; no production predicate changed. The intermediate17aea6d1 contained the first test edit only; it is superseded and carries no qualification claim. A fresh full normal hosted check set runs on68e7f3d. No local container or acquisition was used for this two-line correction. Source and installed delivery remain unmerged/unreleased.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Second source addendum (after 6717795667): SOURCE PASS for the test-only successor.

Subject (exact):

  • Head 68e7f3d9030d290f31adece43e63ff730d3aae8a, tree 88b3f26df228a1d7b50701ebf12c453c8766d80b.
  • Chain: 4336420d → 17aea6d1 (tree 7ee6048c) → 68e7f3d9. Both new commits sit on the reviewed 4336420d, and the merge-base with base 36961d60 is unchanged.
  • Successor-only delta against 4336420d: 1,850 B / e304671f557021a61e447d29b9f9128168ea6b574ff3b8c033db0a89b7385aef. I read it in full.
  • Full diff against the base: 49,258 B.

The delta changes two data-provider rows only. In each, the "future minor" input moves from '1.22' to '1.23' and still expects unsupported_protocol_version:

  • tests/Unit/V2/DefaultWorkflowTaskBridgeServiceOperationTest.php: unsupportedCompletionProtocols;
  • tests/Feature/V2/V2WebhookWorkflowTest.php.

This follows from Core VERSION = '1.22' and isSupportedRequestVersion('1.22') === true, so 1.22 is no longer a future minor. The other rows in both providers are unchanged (malformed patch, different major, leading zeros, missing, empty), and so are their reasons.

What still holds:

  • No src, corpus or fixture bytes changed.
  • The positive 1.22 assertions remain in WorkerProtocolVersionTest: lines 22, 34 and 42, plus isSupportedRequestVersion('1.23') === false at line 43.
  • No other test in the tree uses '1.22' as an unsupported version.

This explains the 4336420d hosted NONPASS (aggregate plus pr-feature-mysql), which stays attributed to that head. All earlier source conclusions are unchanged. PR checks on this exact head are still required, as is the full php.yml source qualification you plan to bind. This addendum makes no release or runtime claim.

@rmcdaniel

Copy link
Copy Markdown
Member Author

One full hosted source qualification selected; no integration or release.

Draft PR1067 exact head 68e7f3d9030d290f31adece43e63ff730d3aae8a, tree 88b3f26df228a1d7b50701ebf12c453c8766d80b, base/main 36961d60921dd7190890a505d9364f1f712a8d63. Fresh PR checks are terminal17success/7intendedskip/0bad. Independent source review and both addenda bind this source; latest6717889462 covers the final two test-only future-version corrections. Earlier corpus-growth and stale-test NONPASSs stay attributed.

The repository AGENTS.md requires ECS, static analysis, unit, coverage and feature qualification. Pull-request gates intentionally skip the full database/coverage matrix. General selects one workflow_dispatch of existing build workflow 20934911 / .github/workflows/php.yml, on branch fix/condition-occurrence-deadline-general-20261108, with only sqlite_timer_qualification=false. Workflow file SHA-256 89fb10b43ac5938bcf8d6468993f862b8839eeaae9aaf76ad533ef49d6c723a6 is unchanged from base. This maintained route runs full unit coverage, MySQL/PostgreSQL shards, MariaDB, source-upgrade and tracing checks. Its main-only Sonar publication job is skipped on this topic ref. No release/tag/deployment or optional real timer workload is selected.

Before POST, re-read remote topic, PR head, base/main and exact check set; refuse drift, bad/unknown states or an existing manual run for this head. Freeze the topic during qualification. Record/fsync the attempted marker, send one dispatch without write retry, and discover its unique attempt1 workflow_dispatch run by workflow, actor, branch, exact head and creation time within120seconds. An uncertain dispatch is reconciled read-only, never repeated. Keep returned IDs and raw API records.

Start by06:00Z. General owns watch to 07:10Z; if that exact run is still active then, one ordinary cancellation after rechecking its immutable identity, and terminal reconciliation by07:15Z. Any assertion, acquisition, timeout or unknown result is attributed NONPASS; no automatic rerun. Normal per-job limits stay unchanged. Routine06:00 health/backup and alerts preempt observation work without altering this source. Retain bounded logs/artifacts for qualification review; a green dispatch must still be assessed before ready/merge and actual-main custody. #1066 and installed #269 acceptance stay open.

@sonarqubecloud

sonarqubecloud Bot commented Nov 8, 2026

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Full qualification NONPASS; one test-only successor prepared.

The full maintained build run 42452557763, attempt 1 on 68e7f3d9030d290f31adece43e63ff730d3aae8a, is terminal: 16 successful jobs, 5 gated skips and 2 failures (unit coverage plus the aggregate build). The coverage unit target ran 5,928 tests and 80,745 assertions, with one failure: SurfaceStabilityContractTest still expected the default advertised protocol to be 1.21 after the source moved it to 1.22. The full MySQL, PostgreSQL, MariaDB, source-upgrade, tracing, quality and corpus jobs succeeded. Coverage upload and the combined coverage gate were skipped after the unit failure; no full qualification is accepted.

Successor e5e161699d920ab127713a7e5cc033de79b3e90e, tree 7932c71047735136ec1b156259b4ab0e4804016d, changes only that unit test: current advertised expectation 1.21 → 1.22 and an explicit accepted-request 1.22 assertion. The historical 1.21 acceptance remains. Successor diff: 1,492 bytes / SHA-256 3a8ace9594ffab10cf8e588cd6fe9e7e4bd551ecfb43c63a4ab6d27f4957181f. All production, corpus and workflow bytes are unchanged.

A bounded local check on the cached exact PHP image passed selected ECS and the SurfaceStability/WorkerProtocol tests: 46 tests, 384 assertions, exit 0, with the container explicitly absent afterward (06:19:47–06:19:48 UTC). This is a local source observation, not a replacement for the full maintained qualification. The earlier corpus, stale future-version and full-coverage NONPASSs remain attributed. A new full exact-head invocation needs its own recorded selection; no rerun of the old failed jobs, integration, tag or release follows from this correction.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Third source addendum, test-only: SOURCE PASS for e5e161699d920ab127713a7e5cc033de79b3e90e.

Subject:

  • Head e5e16169…, tree 7932c71047735136ec1b156259b4ab0e4804016d, sole parent 68e7f3d9, the head of my second addendum 6717889462.
  • Delta: 1,492 B / 3a8ace9594ffab10cf8e588cd6fe9e7e4bd551ecfb43c63a4ab6d27f4957181f. I read all of it: 1 file, +2/−1.
  • Full diff against base 36961d60: 50,750 B, 16 files.

Change: only tests/Unit/V2/SurfaceStabilityContractTest.php.

  • default_advertised_version is now expected to be '1.22' instead of '1.21'.
  • A new assertion checks accepted_request_versions_by_default[22] === '1.22'.
  • The [0], '1.2', [19], [20] and [21] ('1.21') assertions are kept, and so are the header rule, response version and fail-closed list.

Source agreement: SurfaceStabilityContract::workerProtocolNegotiation() sets default_advertised_version to WorkerProtocolVersion::VERSION, which is '1.22' on this head. It builds the accepted list as 1.0 … 1.<minor> from the same constant, so index 22 is '1.22' and is the last entry. That matches the earlier isSupportedRequestVersion rule: 1.20–1.22 accepted, 1.23 refused.

No src, corpus or fixture bytes change. This explains the 68e7 hosted unit NONPASS, which stays attributed to that head. All earlier conclusions are unchanged.

Optional, non-blocking: an assertCount(23, …) would also pin the upper bound, so a future bump has to update this test deliberately.

The full maintained qualification of this exact head is still required. This addendum makes no release claim.

@rmcdaniel

Copy link
Copy Markdown
Member Author

One fresh full hosted source qualification selected; no integration or release.

The previous full run 42452557763 remains NONPASS, with its stale protocol expectation and exact correction recorded in 6718266369.

Selected subject: head e5e161699d920ab127713a7e5cc033de79b3e90e, tree 7932c71047735136ec1b156259b4ab0e4804016d, base/main 36961d60921dd7190890a505d9364f1f712a8d63. The sole successor change is the reviewed test correction; production, corpus and workflow bytes are unchanged. Fresh pull-request checks are terminal: 17 successes, 7 intended skips, no bad states. The local protocol tests passed 46 tests and 384 assertions. Independent Server review of the prior production source remains applicable; a narrow test addendum is requested.

General selects one new workflow_dispatch of maintained workflow 20934911, .github/workflows/php.yml, on fix/condition-occurrence-deadline-general-20261108, with only sqlite_timer_qualification=false. Workflow SHA-256 is unchanged: 89fb10b43ac5938bcf8d6468993f862b8839eeaae9aaf76ad533ef49d6c723a6. This runs full unit coverage, database feature shards, source-upgrade, tracing and quality gates required by AGENTS.md. Main-only publication jobs remain gated by the maintained workflow. No optional timer workload, tag, release or deployment is selected.

Immediately re-read exact remote head, base/main, draft/CLEAN state and terminal check set, and refuse any drift or existing manual run for this head. Freeze the topic. Fsync an exclusive attempt marker before one dispatch POST, without write retry; discover and record the unique attempt-1 run by workflow, actor, branch, head and creation time. Unknown dispatch is reconciled read-only and never repeated.

Start by 06:45 UTC. General owns observation through 07:55 UTC. If the exact run is still active then, recheck immutable identity and issue one ordinary cancellation, with terminal reconciliation by 08:00. Any failure, timeout, acquisition refusal or unknown state remains attributed NONPASS; no automatic retry. A green result still requires assessment of the actual suite and coverage before a separate ready/merge decision and main custody. Issue #1066 and installed #269 acceptance remain open. Routine service health and alerts retain priority.

@rmcdaniel rmcdaniel changed the title Preserve opted-in condition occurrence wall deadlines Preserve opted-in condition occurrence deadlines across false wakes Nov 8, 2026
@codecov

codecov Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.41270% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.09%. Comparing base (36961d6) to head (e5e1616).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
src/V2/Support/ConditionOccurrenceDeadline.php 97.22% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1067      +/-   ##
==========================================
+ Coverage   94.08%   94.09%   +0.01%     
==========================================
  Files         608      609       +1     
  Lines       84837    84956     +119     
==========================================
+ Hits        79817    79943     +126     
+ Misses       5020     5013       -7     
Flag Coverage Δ
v2 94.09% <98.41%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rmcdaniel

Copy link
Copy Markdown
Member Author

FULL SOURCE QUALIFICATION ACCEPTED; one guarded merge selected.

Exact head e5e161699d920ab127713a7e5cc033de79b3e90e, tree 7932c71047735136ec1b156259b4ab0e4804016d, base/main 36961d60921dd7190890a505d9364f1f712a8d63. Independent source review and the third test-only addendum bind this source. The PR remains CLEAN and mergeable, with no source drift.

The one fresh maintained full run 42455200291 completed SUCCESS at 06:56:46 UTC: 18 successful jobs and 5 intended skips. Unit coverage passed 5,928 tests / 80,823 assertions; 15 PHPUnit notices and 49 skipped cases remain visible. All four MySQL shards, all four PostgreSQL shards, MariaDB, both source-upgrade cells, tracing, quality, repository contracts and the replay corpus succeeded. The combined coverage gate passed 93.90% (76,801/81,785) against the unchanged 93.08% accepted baseline. Exact-head checks total 49: 38 successes, 11 skips, no bad or pending states; the commit-status list is empty.

The repository quality cycle is met by these maintained source jobs and the recorded local ECS/static/targeted checks. The earlier corpus-growth, future-version fixture and first-full manifest-test NONPASSs remain attributed; none was relabelled or retried in place.

General selects one ordinary merge of this exact head after an immediate re-read of head, base/main, full checks and CLEAN state. Mark ready once, then merge with match-head protection; no bypass or force. Expected ordered merge parents are [36961d6, e5e1616], with the exact reviewed tree above. Re-read the actual main commit, tree, parents and signature, then observe actual-main checks through terminal. Retain the topic until those checks are green, then delete only that merged remote branch after the ancestor check. Any drift or bad/unknown state stops further effects. Main qualification observation is owned through 08:00 UTC with a terminal/status report by 08:05; no automatic rerun.

This accepts source only and closes no installed #269 gate. Issue #1066 remains open for package delivery and downstream qualification. No tag, package/GitHub Release, PHP Server release, deployment or runtime is selected. The later release notes must scope unchanged per-open behavior to legacy chains and document rollback restrictions for anchored history.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 8, 2026 06:59
@rmcdaniel
rmcdaniel merged commit 269e0c0 into main Nov 8, 2026
49 checks passed
@rmcdaniel

Copy link
Copy Markdown
Member Author

Merged source custody recorded; actual-main checks pending.

The qualified-head merge selection 6718493628 executed once, with match-head protection and no bypass. Main is 269e0c01ab7421c9a6d0acc4bedf79605921786e, with ordered parents [36961d60921dd7190890a505d9364f1f712a8d63, e5e161699d920ab127713a7e5cc033de79b3e90e]. Its tree is 7932c71047735136ec1b156259b4ab0e4804016d, exactly the reviewed and fully qualified head tree. GitHub reports the merge signature valid.

The source full qualification is accepted as recorded. General owns observation of the actual-main checks through terminal; the merged topic remains until those checks are green and its ancestor relationship is verified. No source drift, old-run retry, tag or package release occurred. Issue #1066 remains open for library delivery and downstream installed acceptance. The later release metadata/notes change must preserve this source, clarify legacy per-open behavior and include the anchored-history rollback restriction. PHP Server release and all runtime effects remain unselected.

@rmcdaniel
rmcdaniel deleted the fix/condition-occurrence-deadline-general-20261108 branch November 8, 2026 07:34
@rmcdaniel

Copy link
Copy Markdown
Member Author

Actual-main custody accepted.

Main 269e0c01ab7421c9a6d0acc4bedf79605921786e is signed and verified (valid), with ordered parents [36961d60, e5e16169] and tree 7932c71047735136ec1b156259b4ab0e4804016d, exactly the qualified head tree. The direct API read finds 28 terminal check runs: 25 success and three intended PR-only skips (pr-feature-mysql, pr-tracing, pr-unit-contracts). Both commit statuses, Codecov project and patch, are success. There are no bad, pending or unknown check states.

The actual-main full build, including unit/combined coverage, all MySQL/PostgreSQL shards, MariaDB, tracing, both embedded upgrade cells, corpus and quality, passed. Build run 42456938720 completed at 07:21:35Z; Codecov statuses completed at 07:21:51Z. The earlier failed qualifications remain attributed to their original heads; the successful full dispatch and its exact-head evidence remain recorded above.

After verifying that the qualified head is an ancestor of this main, I deleted only fix/condition-occurrence-deadline-general-20261108 and confirmed GitHub returns 404 for that ref. The source integration is complete. Workflow 2.22.0 publication and its downstream installed acceptance remain under #1066; no tag or package publication is claimed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant